package com.zephyr.vchcenter.dao.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.criterion.Example;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.zephyr.vchcenter.bean.Pagination;
import com.zephyr.vchcenter.dao.IBaseDao;

public class HibernateBaseDaoImpl extends HibernateDaoSupport implements
		IBaseDao {

	private static final Logger log = Logger
			.getLogger(HibernateBaseDaoImpl.class);

	public void delete(Object transientInstance) {
		try {
			log.debug("deleting Object instance: " + Object.class);
			getHibernateTemplate().delete(transientInstance);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}

	public List findByExample(Object instance) {
		log.debug("finding Object instance by example: " + Object.class);
		Session ss = this.getSession();
		Example ex = Example.create(instance).excludeNone().excludeZeroes();
		List results = ss.createCriteria(instance.getClass()).add(ex).list();

		log.debug("find by example successful, result size: " + results.size());

		return results;
	}

	public void saveOrUpdate(final Object transientInstance) {
		this.getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				session.saveOrUpdate(transientInstance);
				return null;
			}
		});
	}

	public Object findById(String clazz, String id) {
		log.debug("getting Object instance with id: " + id);
		Session ss = this.getSession();
		List result = ss.createQuery(
				"from " + clazz + " as c where c.id = :cid").setString("cid",
				id).list();

		Object instance = null;
		if (result.size() > 0)
			instance = result.get(0);
		return instance;
	}

	public Pagination paging(Pagination pagination) {
		int pageNum = pagination.getCurrentPages();
		int pageSize = pagination.getPageSize();
		String hql = pagination.getHql();
		int numBegin = 0;
		if (pageNum < 1) {
			numBegin = 0;
		} else {
			numBegin = (pageNum - 1) * pageSize;
		}
		List retList = new ArrayList();
		Session session = this.getSession();
		try {
			Query query = session.createQuery(hql);
			ScrollableResults sr = query.scroll();
			sr.last();
			int totalSize = sr.getRowNumber() + 1;
			query.setFirstResult(numBegin);
			query.setMaxResults(pageSize);
			retList = query.list();
			
			pagination.setTotalResults(totalSize);
			pagination.setResults(retList);
			return pagination;
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		return pagination;
	}

}
